package com.ssy.lingxi.logistics.serviceimpl;

import cn.hutool.extra.pinyin.PinyinUtil;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.logistics.api.dto.request.CommonIdRequest;
import com.ssy.lingxi.logistics.api.enums.CooperateTypeEnum;
import com.ssy.lingxi.logistics.entity.Company;
import com.ssy.lingxi.logistics.model.enums.CommonStatusEnum;
import com.ssy.lingxi.logistics.model.enums.LogisticsOrderStatusEnum;
import com.ssy.lingxi.logistics.model.request.CommonStatusRequest;
import com.ssy.lingxi.logistics.model.request.CompanyRequest;
import com.ssy.lingxi.logistics.model.response.CompanyListResponse;
import com.ssy.lingxi.logistics.model.response.CompanyResponse;
import com.ssy.lingxi.logistics.repository.CompanyRepository;
import com.ssy.lingxi.logistics.repository.LogisticsOrderRepository;
import com.ssy.lingxi.logistics.service.ICompanyService;
import com.ssy.lingxi.product.api.feign.ICommodityFeign;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 物流公司服务实现类
 * @author yzc
 * @version 2.0.0
 * @date 2020/7/10
 */
@Service
public class CompanyServiceImpl implements ICompanyService {

    @Resource
    private CompanyRepository companyRepository;
    @Resource
    private ICommodityFeign commodityFeign;
    @Resource
    private LogisticsOrderRepository logisticsOrderRepository;

    @Override
    public Wrapper<PageData<CompanyListResponse>> pageCompany(PageVO request, UserLoginCacheDTO loginUser) {
        Pageable page = PageRequest.of(request.getCurrent() - 1, request.getPageSize(), Sort.by("id").ascending());
        Page<Company> pageList = companyRepository.findAllByMemberIdAndRoleId(loginUser.getMemberId(), loginUser.getMemberRoleId(), page);
        List<CompanyListResponse> resultList = pageList.stream().map(e -> {
            CompanyListResponse companyListResponse = new CompanyListResponse();
            companyListResponse.setId(e.getId());
            companyListResponse.setCompanyMemberId(e.getCompanyMemberId());
            companyListResponse.setCompanyRoleId(e.getCompanyRoleId());
            companyListResponse.setName(e.getName());
            companyListResponse.setCode(e.getCode());
            companyListResponse.setCooperateType(e.getCooperateType());
            companyListResponse.setStatus(e.getStatus());
            return companyListResponse;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    @Override
    public Wrapper<CompanyResponse> getCompany(Long id) {
        // 无参返回空
        if (Objects.isNull(id)) {
            return Wrapper.success();
        }
        Company company = companyRepository.findById(id).orElse(null);
        if (Objects.isNull(company)) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }

        CompanyResponse companyResponse = new CompanyResponse();
        companyResponse.setId(company.getId());
        companyResponse.setCompanyMemberId(company.getCompanyMemberId());
        companyResponse.setCompanyRoleId(company.getCompanyRoleId());
        companyResponse.setName(company.getName());
        companyResponse.setCode(company.getCode());
        companyResponse.setCooperateType(company.getCooperateType());
        companyResponse.setStatus(company.getStatus());
        companyResponse.setRemark(company.getRemark());

        return Wrapper.success(companyResponse);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> addCompany(CompanyRequest request, UserLoginCacheDTO loginUser) {
        Company company = new Company();

        // 类型为平台物流
        if (CooperateTypeEnum.PLATFORM.getCode().equals(request.getCooperateType())) {
            // 参数校验
            if (Objects.isNull(request.getCompanyMemberId()) || Objects.isNull(request.getCompanyRoleId())) {
                return Wrapper.fail(ResponseCode.LS_MEMBER_ID_ROLE_ID_VALID);
            }

            // 重复校验
            boolean exists = companyRepository.existsByMemberIdAndRoleIdAndCooperateTypeAndCompanyMemberIdAndCompanyRoleId(loginUser.getMemberId(), loginUser.getMemberRoleId(),
                    CooperateTypeEnum.MERCHANT.getCode(), request.getCompanyMemberId(), request.getCompanyRoleId());
            if (exists) {
                return Wrapper.fail(ResponseCode.LS_DATA_NO_REPEAT);
            }

            company.setCooperateType(request.getCooperateType());
            company.setStatus(CommonStatusEnum.ENABLE.getCode());
            company.setCompanyMemberId(request.getCompanyMemberId());
            company.setCompanyRoleId(request.getCompanyRoleId());
            company.setName(request.getName());
            company.setRemark(request.getRemark());
            company.setMemberId(loginUser.getMemberId());
            company.setRoleId(loginUser.getMemberRoleId());
            company.setCreateTime(System.currentTimeMillis());

            // 保存物流公司
            companyRepository.saveAndFlush(company);
        }

        // 类型为商户合作
        if (CooperateTypeEnum.MERCHANT.getCode().equals(request.getCooperateType())) {

            // 重复校验
            boolean exists = companyRepository.existsByMemberIdAndRoleIdAndCooperateTypeAndNameAndCode(loginUser.getMemberId(), loginUser.getMemberRoleId(),
                    CooperateTypeEnum.MERCHANT.getCode(), request.getName(), request.getCode());
            if (exists) {
                return Wrapper.fail(ResponseCode.LS_DATA_NO_REPEAT);
            }
            //字符串转换大写拼音
            String upperCaseLetter = PinyinUtil.getPinyin(request.getName(), "").toUpperCase();
            //获取首字母
            String firstLetter = upperCaseLetter.substring(0, 1);

            company.setCooperateType(request.getCooperateType());
            company.setStatus(CommonStatusEnum.ENABLE.getCode());
            company.setName(request.getName());
            company.setCode(request.getCode());
            company.setRemark(request.getRemark());
            company.setRoleId(loginUser.getMemberRoleId());
            company.setMemberId(loginUser.getMemberId());
            company.setSort(firstLetter);
            company.setCreateTime(System.currentTimeMillis());

            companyRepository.saveAndFlush(company);
        }

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> updateCompany(CompanyRequest request, UserLoginCacheDTO loginUser) {
        Company company = companyRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(company)) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }

        if (CommonStatusEnum.ENABLE.getCode().equals(company.getStatus())) {
            return Wrapper.fail(ResponseCode.LS_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        // 已被物流单关联不能删除
        boolean flag = logisticsOrderRepository.existsByCompanyId(company.getId());
        if (flag) {
            return Wrapper.fail(ResponseCode.LS_DATA_RELATION_LOGISTICS_ORDER_UPD);
        }

        // 类型为平台物流
        if (CooperateTypeEnum.PLATFORM.getCode().equals(request.getCooperateType())) {
            // 参数校验
            if (Objects.isNull(request.getCompanyMemberId()) || Objects.isNull(request.getCompanyRoleId())) {
                return Wrapper.fail(ResponseCode.LS_MEMBER_ID_ROLE_ID_VALID);
            }

            // 重复校验
            boolean exists = companyRepository.existsByMemberIdAndRoleIdAndCooperateTypeAndCompanyMemberIdAndCompanyRoleIdAndIdNot(loginUser.getMemberId(), loginUser.getMemberRoleId(),
                    CooperateTypeEnum.MERCHANT.getCode(), request.getCompanyMemberId(), request.getCompanyRoleId(), company.getId());
            if (exists) {
                return Wrapper.fail(ResponseCode.LS_DATA_NO_REPEAT);
            }

            company.setCooperateType(CooperateTypeEnum.PLATFORM.getCode());
            company.setCompanyMemberId(request.getCompanyMemberId());
            company.setCompanyRoleId(request.getCompanyRoleId());
            // 清空该字段数据
            company.setCode(null);
            company.setName(request.getName());
            company.setRemark(request.getRemark());

            companyRepository.saveAndFlush(company);
        }

        // 类型为商户合作
        if (CooperateTypeEnum.MERCHANT.getCode().equals(request.getCooperateType())) {

            // 重复校验
            boolean exists = companyRepository.existsByMemberIdAndRoleIdAndCooperateTypeAndNameAndCodeAndIdNot(loginUser.getMemberId(), loginUser.getMemberRoleId(),
                    CooperateTypeEnum.MERCHANT.getCode(), request.getName(), request.getCode(), company.getId());
            if (exists) {
                return Wrapper.fail(ResponseCode.LS_DATA_NO_REPEAT);
            }

            company.setCooperateType(CooperateTypeEnum.MERCHANT.getCode());
            company.setCode(request.getCode());
            // 清空该字段数据
            company.setCompanyMemberId(null);
            company.setCompanyRoleId(null);
            company.setName(request.getName());
            company.setRemark(request.getRemark());

            companyRepository.saveAndFlush(company);
        }

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> updateStatusCompany(CommonStatusRequest request, UserLoginCacheDTO loginUser) {
        Company company = companyRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(company)) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }

        // 商品关联,不能停用
        if (CommonStatusEnum.DISABLE.getCode().equals(request.getStatus())) {
            Wrapper<Boolean> commodityUseCompany = commodityFeign.getCommodityUseCompany(request.getId());
            if (ResponseCode.SUCCESS.getCode() != commodityUseCompany.getCode()) {
                return Wrapper.fail(ResponseCode.SERVICE_PRODUCT_ERROR);
            }
            if (commodityUseCompany.getData()) {
                return Wrapper.fail(ResponseCode.LS_DATA_RELATION_PRODUCT_UPD);
            }
        }

        // 物流单未完成状态
        List<Integer> orderStatus = Arrays.asList(LogisticsOrderStatusEnum.WAIT_SUBMIT.getCode(),
                LogisticsOrderStatusEnum.WAIT_CONFIRMED.getCode(),
                LogisticsOrderStatusEnum.NO_RECEIVE.getCode()
        );

        // 有未执行完的物流单, 不能停用
        int count = logisticsOrderRepository.countByCompanyIdAndStatusIn(request.getId(), orderStatus);
        if (count > 0) {
            return Wrapper.fail(ResponseCode.LS_DATA_EXECUTE_ORDER_UPD);
        }

        company.setStatus(request.getStatus());
        companyRepository.saveAndFlush(company);

        return Wrapper.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> deleteCompany(CommonIdRequest request, UserLoginCacheDTO loginUser) {
        Company company = companyRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(company)) {
            return Wrapper.fail(ResponseCode.LS_RECORDS_DON_T_EXIST);
        }

        if (CommonStatusEnum.ENABLE.getCode().equals(company.getStatus())) {
            return Wrapper.fail(ResponseCode.LS_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }

        // 商品关联,不能删除
        Wrapper<Boolean> commodityUseCompany = commodityFeign.getCommodityUseCompany(request.getId());
        if (ResponseCode.SUCCESS.getCode() != commodityUseCompany.getCode()) {
            return Wrapper.fail(ResponseCode.SERVICE_PRODUCT_ERROR);
        }
        if (commodityUseCompany.getData()) {
            return Wrapper.fail(ResponseCode.LS_DATA_RELATION_PRODUCT_DEL);
        }

        companyRepository.deleteById(company.getId());

        return Wrapper.success();
    }
}